﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PServiceBus.Core.Runtime.Extensions;
using Cassandraemon;


namespace PServiceBus.Cassandra {
    public class CassandraMQ<TObject> : CassandraCollection<TObject> where TObject : class {

        private const string QUEUE_COLUMN_FAMILY = "CFQueues";

        public override IEnumerator<TObject> GetObjects() {
            var client = GetConnection(READ_ONLY_KEY);
            var queue = CassandraPathInfo.Queue;

            PrepareColumnFamily(QUEUE_COLUMN_FAMILY, client);

            while (true) {
                var column = client.ColumnList.Where(x => x.ColumnFamily == QUEUE_COLUMN_FAMILY && x.Key == queue).TakeColumn(1).FirstOrDefault();

                if (column != null && column.Data.Any()) {
                    var item = column.Data[0];

                    client.Column.DeleteOnSubmit(x => x.ColumnFamily == QUEUE_COLUMN_FAMILY && x.Key == queue && x.Column == item.Name);
                    client.SubmitChanges();

                    yield return item.Value.Deserialize<TObject>();
                } else
                    yield break;
            }
        }

        public override bool Add(IEnumerable<TObject> list) {
            Query(client => {
                foreach (var obj in list) Push(client, obj);
            });
            return true;
        }

        public override bool Add(TObject obj) {
            Query(client =>
            {
                Push(client, obj);
            });
            return true;
        }

        private void Push(CassandraContext client, TObject obj) {
            PrepareColumnFamily(QUEUE_COLUMN_FAMILY, client);
            client.Column.InsertOnSubmit(new CassandraEntity<Apache.Cassandra.Column>()
                .SetColumnFamily(QUEUE_COLUMN_FAMILY)
                .SetKey(CassandraPathInfo.Queue)
                .SetData(obj.Serialize(), Cassandraemon.TimeGenerator.GetTimeUUID(DateTime.UtcNow))
                );
        }

        public override void Clear() {
            Query(client =>
            {
                client.Column.DeleteOnSubmit(x => x.ColumnFamily == QUEUE_COLUMN_FAMILY && x.Key == CassandraPathInfo.Queue);
            });
        }

        public override void Delete() {
            Clear();
        }

        public override bool Delete(IEnumerable<Func<TObject, bool>> conditions) {
            throw new NotImplementedException();
        }

        public override bool Delete(IEnumerable<TObject> list) {
            throw new NotImplementedException();
        }

        public override bool Delete(Func<TObject, bool> condition) {
            throw new NotImplementedException();
        }

        public override bool Delete(TObject obj) {
            throw new NotImplementedException();
        }

        public override bool Exists(Func<TObject, bool> condition) {
            throw new NotImplementedException();
        }

        public override bool Exists(TObject obj) {
            throw new NotImplementedException();
        }

        public override TObject Get(Func<TObject, bool> condition) {
            throw new NotImplementedException();
        }

        public override TObject Get(Guid id) {
            throw new NotImplementedException();
        }

        public override bool Refresh(TObject obj) {
            throw new NotImplementedException();
        }
    }
}
